package siddur.traktask.web.controller;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import siddur.traktask.entity.Memo;
import siddur.traktask.entity.ScreenShot;
import siddur.traktask.entity.TaskInfo;
import siddur.traktask.entity.TrakPeriod;
import siddur.traktask.framework.FileSystemUtil;
import siddur.traktask.repository.MemoRepository;
import siddur.traktask.repository.ScreenShotRepository;
import siddur.traktask.repository.TaskRepository;
import siddur.traktask.repository.TrakPeriodRepository;
import siddur.traktask.web.model.DailyData;

/*
 * Handle web ajax request about calendar
 */
@RestController
@RequestMapping("/cal")
public class CalendarController {
	
	private static final Logger log4j = Logger.getLogger(CalendarController.class);
	private static final long ONE_DAY = 1000 * 3600 * 24;
	
	@Autowired TaskRepository taskRep;
	@Autowired ScreenShotRepository ssRep;
	@Autowired MemoRepository memoRep;
	@Autowired TrakPeriodRepository tpRep;
	
	/*
	 * Daily data depends on client's time zone.
	 */
	@RequestMapping("/daily")
	public DailyData dailyData(long start, long taskId){
		Date startAt = new Date(start);
		Date endAt = new Date(start + ONE_DAY);
		TaskInfo task = taskRep.findOne(taskId);
		
		
		List<TrakPeriod> periods = tpRep.findBetween(startAt, endAt, task);
		List<Memo> memos = memoRep.findBetween(startAt, endAt, task);
		List<ScreenShot> screenshots = ssRep.findBetween(startAt, endAt, task);
		DailyData dd = new DailyData(periods, memos, screenshots);
		return dd;
	}
	
	/*
	 * monthly, weekly hours based on server-related time zone
	 * if period is over two months, count startAt
	 */
	@RequestMapping("/seconds")
	public Long[] seconds(long taskId){
		Calendar today1 = DateUtils.truncate(Calendar.getInstance(), Calendar.DATE);
		Calendar today2 = DateUtils.truncate(Calendar.getInstance(), Calendar.DATE);
		today1.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
		today2.set(Calendar.DAY_OF_MONTH, 1);
		Date weekStart = today1.getTime();
		Date monthStart = today2.getTime();
		
		Long weekData = tpRep.getSumOfSeconds(weekStart, taskId);
		Long lastWeek = tpRep.getSumOfSeconds(DateUtils.addWeeks(weekStart, -1), weekStart, taskId);
		Long monthData = tpRep.getSumOfSeconds(monthStart, taskId);
		Long lastMonth = tpRep.getSumOfSeconds(DateUtils.addMonths(monthStart, -1), monthStart, taskId);
		return new Long[]{weekData, lastWeek, monthData, lastMonth};
	}
	
	@RequestMapping("/img")
	public void image(long id, String s, HttpServletRequest req, HttpServletResponse resp){
		ScreenShot ss = ssRep.findOne(id);
		File f = new File(FileSystemUtil.getImageDir(), s == null ? ss.getSmallImageURL() : ss.getImageURL());
		
		resp.setContentType("image/jpeg");
		if(f.isFile()){
			long lastMotify = req.getDateHeader("If-Modified-Since");
			if(lastMotify >= f.lastModified()){
				resp.setStatus(304);
			}else{
				InputStream input = null;
				OutputStream output = null;
				try {
					input = new FileInputStream(f);
					output = resp.getOutputStream();
					IOUtils.copy(input, output);
				} catch (IOException e) {
					resp.setStatus(500);
				} finally {
					IOUtils.closeQuietly(input);
					IOUtils.closeQuietly(output);
				}
			}
		}else{
			resp.setStatus(404);
		}
	}
	
}
